#!/bin/zsh

LDAP_LOG_LEVEL=${LDAP_LOG_LEVEL:-"64"}
LDAP_DOMAIN=${LDAP_DOMAIN-"domain"}
LDAP_SUBDOMAIN=${LDAP_SUBDOMAIN:-"openldap"}
LDAP_USER=${LDAP_USER:-"ldap"}
LDAP_GROUP=${LDAP_GROUP:-"ldap"}
LDAP_CONFIG_DIR=${LDAP_CONFIG_DIR:-"/etc/openldap/slapd.d"}
LDAP_URL=${LDAP_URL:-"ldap:///"}
LDAP_ROOT_DN=${LDAP_ROOT_DN:-"cn=root,dc=${LDAP_SUBDOMAIN},dc=${LDAP_DOMAIN}"}
LDAP_ROOT_PASSWORD_INPUT=${LDAP_ROOT_PASSWORD_INPUT:="123321"}
# LDAP_ROOT_PASSWORD=`slappasswd -s ${LDAP_ROOT_PASSWORD_INPUT}`
LDAP_ROOT_PASSWORD=${LDAP_ROOT_PASSWORD_INPUT}
# unset LDAP_ROOT_PASSWORD_INPUT

LDAP_LOG_FILE=/var/log/openldap.log

log () {
	echo $1 | /usr/bin/tee -a ${LDAP_LOG_FILE}
}

function get_pid () {
	PATTERN=$1
	/bin/ps aux|/bin/grep "${PATTERN}" | /bin/sed '/grep/d'| /usr/bin/awk '{print $1}'
}

test_slapd () {
	log "Testing slapd config"
	/usr/sbin/slaptest -u
	log "slapd config tested"
}

create_slapd_ldif () {
	mkdir -p /var/run/openldap
	mkdir -p /etc/openldap/certs
	cat > ${SLAPD_LDIF} <<EOF
# file: /etc/openldap/slapd.ldif
dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/run/openldap/slapd.args
olcPidFile: /var/run/openldap/slapd.pid
olcTLSCertificateFile: /etc/openldap/certs/server.crt
olcTLSCertificateKeyFile: /etc/openldap/certs/server.key
olcTLSCACertificateFile: /etc/openldap/cacerts/cacert.pem

dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema

include: file:///etc/openldap/schema/core.ldif
include: file:///etc/openldap/schema/cosine.ldif
include: file:///etc/openldap/schema/nis.ldif
include: file:///etc/openldap/schema/inetorgperson.ldif

dn: olcDatabase=frontend,cn=config
objectClass: olcDatabaseConfig
objectClass: olcFrontendConfig
olcDatabase: frontend

dn: olcDatabase=config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: config
olcAccess: to * 
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage 
  by * none

dn: olcDatabase=monitor,cn=config
objectClass: olcDatabaseConfig
olcDatabase: monitor
olcAccess: to * 
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read 
  by dn.base="cn=Manager,dc=black,dc=com" read 
  by * none

EOF
}

modify_slapd_ldif () {
	/bin/sed 's/([a-zA-Z0-9]*).la/\1.so/g' ${SLAPD_LDIF} > /tmp/slapd.ldif
	SHOULD_BE_SAME=`/usr/bin/diff ${SLAPD_LDIF} /tmp/slapd.ldif`
	if [ ! -z ${SHOULD_BE_SAME} ]; then
		echo "/etc/openldap/slapd.ldif and /tmp/slapd.ldif differ."
	fi
	/bin/sed -i "s/^olcSuffix: dc=\(.*\),dc=\(.*\)$/olcSuffix: dc="${LDAP_SUBDOMAIN}",dc="${LDAP_DOMAIN}"/g" ${SLAPD_LDIF}
	/bin/sed -i "s/^olcRootDN: cn=\(.*\),dc=\(.*\),dc=\(.*\)$/olcRootDN: "${LDAP_ROOT_DN}"/g" ${SLAPD_LDIF}
	/bin/sed -i "s/^olcRootPW: secret/olcRootPW: "${LDAP_ROOT_PASSWORD}"/g" ${SLAPD_LDIF}
}

apply_slapd_ldif () {
	echo "clear ${LDAP_CONFIG_DIR}"
	/bin/rm -f ${LDAP_CONFIG_DIR}/cn=config.ldif
	/bin/rm -rf ${LDAP_CONFIG_DIR}/cn=config/
	# import ${SLAPD_LDIF} 
	echo "import ${SLAPD_LDIF}"
	/usr/sbin/slapadd -n 0 -F ${LDAP_CONFIG_DIR} -l ${SLAPD_LDIF}
	/bin/chown -R ldap:ldap ${LDAP_CONFIG_DIR}/*
}

config_slapd () {
	log "Configure slapd"
	/usr/bin/install -m 755 -o ldap -g ldap -d ${LDAP_CONFIG_DIR}
	/usr/bin/install -m 755 -o ldap -g ldap -d /var/lib/openldap/run
	##  /etc/conf.d/slapd 
	# Comment out cfgfile="/etc/openldap/slapd.conf"
	/bin/sed -i 's,^cfgfile=,#cfgfile=,g' /etc/conf.d/slapd 
	# Uncomment cfgdir="/etc/openldap/slapd.d"
	/bin/sed -i 's,^#cfgdir=.*$,cfgdir="/etc/openldap/slapd.d",g' /etc/conf.d/slapd 

	# remove /etc/openldap/slapd.conf if it exists.
	[ -f /etc/openldap/slapd.conf ] && /bin/rm /etc/openldap/slapd.conf

	# prepare /etc/openldap/slapd.d
	/bin/mkdir -p ${LDAP_CONFIG_DIR}

	# prepare /etc/openldap/slapd.ldif
	SLAPD_LDIF=/etc/openldap/slapd.ldif
	log "create slapd ldif"
	create_slapd_ldif

	log "modify slapd ldif"
	modify_slapd_ldif

	log "apply slapd ldif"
	apply_slapd_ldif
	OPENLDAP_INSTALLED=1
	log "slapd configured"
	test_slapd
}

import_ldif () {
	LDIF=$1
	echo -n "importing LDIF=${LDIF}"
	if [ -f ${LDIF} ]; then
		/usr/bin/ldapadd -x -D ${LDAP_ROOT_DN} -w ${LDAP_ROOT_PASSWORD_INPUT} -f ${LDIF}
		echo "[ "${GREEN_START}"OK"${GREEN_STOP}" ]"
	else
		log "${LDIF} was not found"
		echo "["${RED_START}"FAILED"${RED_STOP}"]"
	fi
}

import () {
	BASE_LDIF=/srv/podman/openldap/base.ldif
	echo "import ldif ${BASE_LDIF}"
	import_ldif ${BASE_LDIF}
	SCHEMA_DIR=/etc/openldap/schema
	SCHEMA_LDIF=`ls ${SCHEMA_DIR}/*.ldif`
	for path in ${SCHEMA_LDIF};
	do
		echo "import ldif ${path}"
		import_ldif ${path}
	done
}

OPENLDAP_INSTALLED=${OPENLDAP_INSTALLED:-"0"}
install_openldap ()  {
	echo "installing openldap"
	if [ ${OPENLDAP_INSTALLED} -eq 0 ]; then
		config_slapd
		OPENLDAP_INSTALLED=1
	fi
	echo "Installed openldap: ${OPENLDAP_INSTALLED}"
}


SLAPD_PATTERN="/usr/sbin/slapd"

status () {
	echo -n "openldap status: "
	SLAPD_PID=`get_pid ${SLAPD_PATTERN}`
	if [ ${SLAPD_PID} = "" ]; then
		log "slapd was not running. "
		if [ ! -f /usr/sbin/slapd ]; then
			log "/usr/sbin/slapd was not found"
		   	install
		fi
		echo "[ "${RED_START}"FAILED"${RED_STOP}" ]"
		return 1;
	else
		echo "[ "${GREEN_START}"OK"${GREEN_STOP}" ]"
		return 0;
	fi
}

start () {
	echo "start openldap: "
	status || install_openldap > /dev/null
	if [ $? ]; then
		echo -n "start phpldapadmin: "
		/srv/entrypoint.d/phpldapadmin start > /dev/null
		echo "[ "${GREEN_START}"OK"${GREEN_STOP}" ]"
		echo -n "execute /usr/sbin/slapd: "
		if [ "$1" = "-k" ]; then
			exec /usr/sbin/slapd -d ${LDAP_LOG_LEVEL} -u ${LDAP_USER} -g ${LDAP_GROUP} -F ${LDAP_CONFIG_DIR} -h ${LDAP_URL} 2>1 > /dev/null
		else
			/usr/sbin/slapd -d ${LDAP_LOG_LEVEL} -u ${LDAP_USER} -g ${LDAP_GROUP} -F ${LDAP_CONFIG_DIR} -h ${LDAP_URL} 2>1 > /dev/null
		fi
		echo "[ "${GREEN_START}"OK"${GREEN_STOP}" ]"
	fi
	echo "[ "${GREEN_START}"OK"${GREEN_STOP}" ]"
}

main () {
	action=$1
	case $action in 
		install)
			install_openldap
			;;
		status)
			status
			;;
		start)
			start
			;;
		config)
			config_slapd
			;;
		test)
			test_slapd
			;;
		import)
			import
			;;
		*)
	esac
}

main $@

